package test.driver;

import java.io.File;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;

import test.utils.Config;

public class MyHttp {
	private String url;   //请求地址
	private HashMap<String, String> param;  //请求数据
	private String response;  //返回结果
	private Map<String, String> file; //上传的文件
	private String cookie; 
	private String header;
	private String body;
	private boolean isProxy = false;  //默认不使用
	private String proxyUrl;
	private int proxyPort;
	private Map<String, String> myHeaders;
	private int responseStatusCode;
	public JSONObject headersObject = new JSONObject();

	//构造函数，初始化文件列表
	public MyHttp() {
		file = new HashMap<>();
		myHeaders = new HashMap<>();
		body = "";
	}
	
	public void seturl(String uri) {
		url = uri;
	}
	
	public void setparam(HashMap<String, String> params) {
		param = params;
	}
	
	public void setfile(String key, String value) {
		file.put(key, value);
	}
	
	/**
	 * 带cookies的post请求方法
	 * @param content_type
	 */
	public void post(String content_type) throws Exception {
		CloseableHttpClient client = null;
		SSLContext sslcontext = createIgnoreVerifySSL();  
        //设置协议http和https对应的处理socket链接工厂的对象  
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()  
            .register("http", PlainConnectionSocketFactory.INSTANCE)  
            .register("https", new SSLConnectionSocketFactory(sslcontext))  
            .build();  
        PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);  
        HttpClients.custom().setConnectionManager(connManager); 
        //创建自定义的httpclient对象  
        client = HttpClients.custom().setConnectionManager(connManager).build();  
//		CloseableHttpClient client = HttpClientBuilder.create().build();
		HttpPost post = new HttpPost(url);
		if(isProxy) {
			setProxy(post);
		}
		String str = "";
		if(!content_type.equals(Config.form)) {
			str = body;
		}
		else {
			if (body != null && !"".equals(body)) {
				str = body;
			}else {
				str = mapToUrlString(param);
			}
		}
		if (str == null) {
			str = "";
		}
		StringEntity reqEntity = new StringEntity(str, "UTF-8");
		post.setHeader("content-type", content_type);
		if(cookie != null && !cookie.isEmpty()){
			post.setHeader("Cookie", cookie);
		}
		//设置个性化的header
		if (myHeaders != null) {
			for (Entry<String, String> entry : myHeaders.entrySet()) {
				post.setHeader(entry.getKey(), entry.getValue());
			}
		}
		post.setEntity(reqEntity);
		HttpResponse response1 = client.execute(post);
		setResponseStatusCode(response1.getStatusLine().getStatusCode());
		if(getResponseStatusCode() != 200 && getResponseStatusCode() != 302) {
			response = "";
		}else {
			response = EntityUtils.toString(response1.getEntity());
		}	
		
		Header [] headers = response1.getAllHeaders();
		for(int i=0; i<headers.length; i++){
			headersObject.put(headers[i].getName(), headers[i].getValue());
		}
		
		setHeader(headersObject.toString());
		if (headersObject.has("Set-Cookie")) {
			try {
				cookie = headersObject.getString("Set-Cookie");
			} catch (JSONException e) {
				e.printStackTrace();
			}
		}
		else {
			cookie = "";
		}
		client.close();
		if (param != null) {
			param.clear();
		}
	}
	
	public static String htmlEncode(String source) {
        if (source == null) {
            return "";
        }
        String html = "";
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < source.length(); i++) {
            char c = source.charAt(i);
            switch (c) {
            case '<':
                buffer.append("<");
                break;
            case '>':
                buffer.append(">");
                break;
            case '&':
                buffer.append("&");
                break;
            case '"':
                buffer.append("\"");
                break;
            case '\'':
                buffer.append("\'");
                break;
            case 10:
            case 13:
                break;
            default:
                buffer.append(c);
            }
        }
        html = buffer.toString();
        return html;
    }
	
	/**
	 * post请求带文件上传功能
	 * @return
	 */
	public void postWithFile(String content_type) throws Exception {
		CloseableHttpClient cilent = HttpClients.createDefault();
		HttpPost post = new HttpPost(url);
		setProxy(post);
		if(cookie != null && !cookie.isEmpty()){
			post.setHeader("Cookie", cookie);
		}
		//设置个性化的header
		if (myHeaders != null) {
			for (Entry<String, String> entry : myHeaders.entrySet()) {
				post.setHeader(entry.getKey(), entry.getValue());
			}
		}
		MultipartEntityBuilder multiEntityBuilder = MultipartEntityBuilder
				.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
		Iterator<Entry<String, String>> fileinfo = file.entrySet().iterator();
		while (fileinfo.hasNext()) {
			Map.Entry<String, String> entry = fileinfo
					.next();
			String fileName = entry.getKey().toString();
			String filePath = entry.getValue().toString();
			File file = new File(filePath);
			FileBody bin = new FileBody(file);
			multiEntityBuilder.addPart(fileName, bin);
		}

		Iterator<Entry<String, String>> it = param.entrySet().iterator();
		ContentType contentType = ContentType.create(content_type, "UTF-8");
		while (it.hasNext()) {
			Map.Entry<String, String> entry = it
					.next();
			String key = entry.getKey().toString();
			String value = entry.getValue().toString();
			
			StringBody part = new StringBody(value,
					contentType);
			multiEntityBuilder.addPart(key, part);
			
		}

		HttpEntity reqEntity = multiEntityBuilder.build();

		post.setEntity(reqEntity);

		CloseableHttpResponse response1 = cilent.execute(post);
		setResponseStatusCode(response1.getStatusLine().getStatusCode());
		JSONObject headersObject = new JSONObject();
		Header [] headers = response1.getAllHeaders();
		for(int i=0; i<headers.length; i++){
			headersObject.put(headers[i].getName(), headers[i].getValue());
		}
		response = EntityUtils.toString(response1.getEntity());
		setHeader(headersObject.toString());
		if (headersObject.has("Set-Cookie")) {
			cookie = headersObject.getString("Set-Cookie");
		}
		else {
			cookie = "";
		}
		response1.close();
		if (param != null) {
			param.clear();
		}
		if (file != null) {
			file.clear();
		}
	}
	
	/**
	 * get请求
	 * @param content_type
	 * @param cookie
	 * @return
	 */
	public void SendGetRequest(String content_type) throws Exception {
		String data = mapToUrlString(param);
		if(data !=null && !data.isEmpty()){
			url = url + "?" + data; 
		}
		CloseableHttpClient client = null;
		SSLContext sslcontext = createIgnoreVerifySSL();  
        //设置协议http和https对应的处理socket链接工厂的对象
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()  
            .register("http", PlainConnectionSocketFactory.INSTANCE)  
            .register("https", new SSLConnectionSocketFactory(sslcontext))  
            .build();  
        PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);  
        HttpClients.custom().setConnectionManager(connManager); 
        //创建自定义的httpclient对象  
        client = HttpClients.custom().setConnectionManager(connManager).build();  
//		client = HttpClientBuilder.create().build();
		HttpGet get = new HttpGet(url);
		setProxy(get);
		if (content_type != null && !"".equals(content_type)) {
			get.setHeader("content-type", content_type);
		}
		if(cookie != null && !cookie.isEmpty()){
			get.setHeader("Cookie", cookie);
		}
		//设置个性化的header
		if (myHeaders != null) {
			for (Entry<String, String> entry : myHeaders.entrySet()) {
				get.setHeader(entry.getKey(), entry.getValue());
			}
		}
		HttpResponse response = client.execute(get);
		Header [] headers = response.getAllHeaders();
		for(int i=0; i<headers.length; i++){
			headersObject.put(headers[i].getName(), headers[i].getValue());
		}
		header = headersObject.toString();
		if (headersObject.has("Set-Cookie")) {
			cookie = headersObject.getString("Set-Cookie");
		}
		else {
			cookie = "";
		}
		setResponseStatusCode(response.getStatusLine().getStatusCode());
		if (response.getStatusLine().getStatusCode() == 302) {
			this.response = headersObject.get("Location").toString();
		}else {
			this.response = EntityUtils.toString(response.getEntity());
		}
		client.close();
		if (param != null) {
			param.clear();
		}
	}

	
	//设置代理
	private void setProxy(HttpPost post) {
		if(isProxy){
			HttpHost proxy = new HttpHost(getProxyUrl()+":"+getProxyPort());  
	        RequestConfig config = RequestConfig.custom().setProxy(proxy).build();  
	        post.setConfig(config);
		}
	}
	
	private void setProxy(HttpGet get){
		if(isProxy){
			HttpHost proxy = new HttpHost(getProxyUrl()+":"+getProxyPort());  
	        RequestConfig config = RequestConfig.custom().setProxy(proxy).build();  
	        get.setConfig(config);
		}
	}

	/**
	 * @return the response
	 */
	public String getResponse() {
		return response;
	}
	
	//遍历map组成参数url形式
	public String mapToUrlString(Map<String, String> map) {
		String str = "";
		String value = "";
		if (map == null) {
			return "";
		}
		for (Entry<String, String> entry:map.entrySet()) {  
			value = entry.getValue();
			if(str == "") {
				str = entry.getKey() + "=" + value;
			}
			else {
				str = str + "&" + entry.getKey() + "=" + value;
			}	
		 }
		return str;
	}
	
	//map转json
	public String mapToJson(Map<String, String> param) {
		JSONObject aJsonObject = new JSONObject(param);
		return aJsonObject.toString();
	}

	/**
	 * @return the cookie
	 */
	public String getCookie() {
		return cookie;
	}

	/**
	 * @param cookie the cookie to set
	 */
	public void setCookie(String cookie) {
		this.cookie = cookie;
	}

	public String getHeader() {
		return header;
	}

	public void setHeader(String header) {
		this.header = header;
	}
	
	public void setBody(String body) {
		this.body = body;
	}

	public boolean getIsProxy() {
		return isProxy;
	}

	public String getProxyUrl() {
		return proxyUrl;
	}

	public int getProxyPort() {
		return proxyPort;
	}

	public void setProxy(boolean isProxy, String proxyUrl, int proxyPort) {
		this.isProxy = isProxy;
		this.proxyUrl = proxyUrl;
		this.proxyPort = proxyPort;
	}

	public void setMyHeaders(Map<String, String> myHeaders) {
		this.myHeaders = myHeaders;
	}

	public int getResponseStatusCode() {
		return responseStatusCode;
	}

	public void setResponseStatusCode(int responseStatusCode) {
		this.responseStatusCode = responseStatusCode;
	}
	
	/** 
	* 绕过验证 
	*   
	* @return 
	* @throws NoSuchAlgorithmException  
	* @throws KeyManagementException  
	*/  
	public static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {  
	        SSLContext sc = SSLContext.getInstance("SSLv3");  

	        // 实现一个X509TrustManager接口，用于绕过验证，不用修改里面的方法  
	        X509TrustManager trustManager = new X509TrustManager() {  
	            @Override  
	            public void checkClientTrusted(  
	                    java.security.cert.X509Certificate[] paramArrayOfX509Certificate,  
	                    String paramString) throws CertificateException {  
	            }  

	            @Override  
	            public void checkServerTrusted(  
	                    java.security.cert.X509Certificate[] paramArrayOfX509Certificate,  
	                    String paramString) throws CertificateException {  
	            }  

	            @Override  
	            public java.security.cert.X509Certificate[] getAcceptedIssuers() {  
	                return null;  
	            }  
	        };  

	        sc.init(null, new TrustManager[] { trustManager }, null);  
	        return sc;  
	    }

}
